import redis
import json
import datetime


class RealTimeView(object):

    def __init__(self, address, port, db=0, password=None):

        print("Connecting Database")
        self.address = address
        self.port = port
        self.username = "admin"
        self.password = password
        #
        pool = redis.ConnectionPool(host=address, port=port, db=db, password=password)
        self.instance = redis.Redis(connection_pool=pool)

    def Serialize(self, document):
        #
        if "_id" in document:
            del document["_id"]
        # 以下转化会把数字转化为字符，导致读取时出现问题
        # for k, v in document.items():
        #    document[k] = str(document[k])

    def Set(self, key, value):
        # s = json.dumps(value)
        self.instance.set(key, value)

    def Get(self, key):
        return self.instance.get(key)

    def MultiSet(self, dict):
        self.instance.mset(dict)

    def MultiGet(self, pattern):
        return self.instance.keys(pattern + "*")

    # ---Push to Realtime View---
    # 储存一个文档 {"A": 0 ,"B": 1}
    def SetDocument(self, key, document):
        #
        self.Serialize(document)
        #
        s = json.dumps(document)
        self.instance.set(key, s)

    # ---Read from Realtime View---
    def GetDocument(self, key):
        j = self.instance.get(key)
        if j == None:
            return
        s = str(j, encoding = "utf-8")
        # quote = eval(s) # Too Slow
        # s = re.sub('\'', '\"', s) # 如果是用 Set 命令设入的Value，要进行单引号替换
        jsonObj = json.loads(s)
        return jsonObj
        # documment = OptionPricer.OptionPricer.Deserializer(jsonObj)
        # return j

    def SetManyDocuments(self, dict):
        #
        for key, value in dict.items():
            self.Serialize(value)
            s = json.dumps(value)
            dict[key] = s
        #
        self.instance.mset(dict)

    # --两侧目录结构 key1 - key2 - document
    def SetManyHashDocuments(self, key, documents):
        count = 0
        for key2, value in documents.items():
            # count += 1
            # print(count)
            s = json.dumps(value)
            self.instance.hset(key, key2, s)

    #
    def GetManyHashDocuments(self, key):
        dic = {}
        keys = self.instance.hkeys(key)
        for key2 in keys:
            value = self.instance.hget(key, key2)
            sKey2 = key2.decode(encoding='utf-8')
            sValue = str(value, encoding="utf-8")
            jsonObj = json.loads(sValue)
            dic[sKey2] = jsonObj
        return dic

    def SetHashDocument(self, key1, key2, document):
        # if "_id" in document:
        #    del document["_id"]
        # for k, v in document.items():
        #     document[k] = str(document[k])
        s = json.dumps(document)
        self.instance.hset(key1, key2, s)

    def GetHashDocument(self, key1, key2, deserialize=True):
        value = self.instance.hget(key1, key2)
        if value == None:
            return None
        #
        s = str(value, encoding="utf-8")
        #
        # if deserialize:
        #     jsonObj = json.loads(s)
        #     return jsonObj
        # else:
        #     return s
        jsonObj = json.loads(s)
        return jsonObj

    def SetHash(self, key1, key2, value):
        self.instance.hset(key1, key2, value)

    def GetHash(self, key1, key2):
        return self.instance.hget(key1, key2)

    def Clear(self):
        self.instance.flushdb()

    def Delete(self, key):
        self.instance.delete(key)

    def Publish(self, channel, message):
        self.instance.publish(channel, message)

    def Subscribe(self, channel, callback=None, print=False):
        pubsub = self.instance.pubsub()
        pubsub.subscribe(channel)

        while(True):
            pubsub.listen()
            msg = pubsub.parse_response()
            if print:
                print("Received @" + str(datetime.datetime.now()) + " " + str(msg))
            if callback != None:
                callback(msg)